﻿using System;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using MultipleChoice_ExamGenerator.VariousUtils;
using MySql.Data.MySqlClient;

namespace MultipleChoice_ExamGenerator
{
    public partial class NewQuestion : Form
    {
        private int _leftColumCounter = 1;          // Μετρητής για την αριστερή στήλη
        private int _rightColumCounter = 1;         // Μετρητής για την δεξιά στήλη
        private int _generatedControlNumber = 3;    // Μεταβλητή για την ονοματοδοσία των νεων Controls 
        private readonly Validators _validator;     // Μας παρέχει κάποιες μεθόδους για το validate των controls

        public NewQuestion()
        {
            InitializeComponent();
            _validator = new Validators();
        }

        // Εισαγωγή έρωτήσεων δυναμικά
        private void addBT_Click(object sender, EventArgs e)
        {
            RichTextBox rtb = new RichTextBox();
            CheckBox cb = new CheckBox();

            // Επιλογή της στήλης για την εισαγωγή των Controls
            // Αν leftColumCounter > rightColumCounter τότε εισάγωμε τα νέα Controls στην δεξιά στήλη
            // Διαφορετικά η εισαγωγή γίνεται στην αριστερή στήλη
            if (_leftColumCounter > _rightColumCounter)
            {
                // Προσθήκη AnsweBox
                rtb.Location = new Point(760, 100 * _rightColumCounter + 405);
                rtb.Size = new Size(300, 70);
                rtb.Font = new Font(rtb.Font.FontFamily, 10);
                rtb.Name = "answerBox" + _generatedControlNumber;

                // Προσθήκη checkBox
                cb.Location = new Point(652, 100 * _rightColumCounter + 405);
                cb.Font = new Font(cb.Font.FontFamily, 10);
                cb.ForeColor = Color.White;
                cb.Name = "answerCB" + _generatedControlNumber;
                cb.Text = "Correct";

                _rightColumCounter++;
            }
            else
            {
                // Προσθήκη AnsweBox
                rtb.Location = new Point(140, 100 * _leftColumCounter + 405);
                rtb.Size = new Size(300, 70);
                rtb.Font = new Font(rtb.Font.FontFamily, 10);
                rtb.Name = "answerBox" + _generatedControlNumber;

                // Προσθήκη checkBox
                cb.Location = new Point(36, 100 * _leftColumCounter + 405);
                cb.Font = new Font(cb.Font.FontFamily, 10);
                cb.ForeColor = Color.White;
                cb.Name = "answerCB" + _generatedControlNumber;
                cb.Text = "Correct";

                _leftColumCounter++;
            }
            _generatedControlNumber++;

            // Εισάγουμε τα Controls στην φόρμα μας
            Controls.Add(cb);
            Controls.Add(rtb);
        }

        private void New_Question_Load(object sender, EventArgs e)
        {
            categoryTableAdapter.FillParentCategories(multiplechoicedbDataSet.category);
            SubCategories();
        }

        private void categoryCB_SelectedIndexChanged(object sender, EventArgs e)
        {
            SubCategories();
        }

        /// <summary>
        /// Αυτή η μέθοδος γεμίζει το categoryCB2 αναλόγως με το επιλεγμένο 
        /// αντικείμενο του categoryCB
        /// </summary>
        private void SubCategories()
        {
            var parentCategoryId = Convert.ToInt32(categoryCB.SelectedValue);

            categoryCB2.ValueMember = "CategoryID";
            categoryCB2.DisplayMember = "CategoryName";
            categoryCB2.DataSource = categoryTableAdapter.GetDataByCategoriesWhereParentID(parentCategoryId);
        }

        // Προσθήκη εικόνων στο PictureBox
        private void QuestionPictureBox_Click(object sender, EventArgs e)
        {
            var newdialog = new OpenFileDialog
            {
                Filter = "Image files (*.jpg, *.jpeg, *.jpe, *.jfif, *.png) | *.jpg; *.jpeg; *.jpe; *.jfif; *.png",
                FilterIndex = 1
            };

            if (newdialog.ShowDialog() == DialogResult.OK)
            {
                var image = new Bitmap(Image.FromFile(newdialog.FileName));
                if (image.Height > 320 || image.Width > 320)
                {
                    QuestionPictureBox.Image = new Bitmap(Image.FromFile(newdialog.FileName), 320, 320);
                }
                else
                {
                    QuestionPictureBox.Image = image;
                }

            }
        }

        private void saveBT_Click(object sender, EventArgs e)
        {
            if (!IsValid()) return;
            #region -- Add new Question - TRANSACTION--
            using (var con = new MySqlConnection(Properties.Settings.Default.multiplechoicedbConnectionString))
            {
                con.Open();
                using (var cmd = new MySqlCommand())
                {
                    using (var trans = con.BeginTransaction(IsolationLevel.Serializable))
                    {
                        try
                        {
                            cmd.Connection = con;

                            // Βάζουμε την ερώτηση στην βάση
                            cmd.CommandText =
                                "INSERT INTO questions(OwnerID, Private, Image, Level, QuestionText, Status)" +
                                "VALUES(@OwnerID, @Private, @Image, @Level, @QuestionText, @Status)";
                            cmd.Parameters.AddWithValue("OwnerID", ActiveAuthor.GetCurrentAuthor());
                            cmd.Parameters.AddWithValue("Private", privateCB.Checked ? 1 : 0);
                            cmd.Parameters.AddWithValue("Image", Utils.ImageToByteArray(QuestionPictureBox.Image));
                            cmd.Parameters.AddWithValue("Level", levelComboBox.SelectedItem.ToString());
                            cmd.Parameters.AddWithValue("QuestionText", QuestionRTB.Text.Trim());
                            cmd.Parameters.AddWithValue("Status", statusCB.SelectedItem.ToString());
                            cmd.ExecuteNonQuery();

                            var qid = cmd.LastInsertedId; // Το ID της ερώτησης που μόλις βάλαμε στην βάση

                            cmd.CommandText = "INSERT INTO question_category(QuestionID, CategoryID)" +
                                              "VALUES(@QuestionId, @cid)";
                            cmd.Parameters.AddWithValue("QuestionId", qid);
                            cmd.Parameters.AddWithValue("cid", categoryCB2.SelectedValue);
                            cmd.ExecuteNonQuery();

                            if (!string.IsNullOrEmpty(tagTB.Text.Trim()))
                            {
                                cmd.CommandText = "INSERT INTO tags(QuestionID, TagText)" +
                                                  "VALUES(@qid, @tagtext)";
                                cmd.Parameters.AddWithValue("qid", qid);
                                cmd.Parameters.AddWithValue("tagtext", tagTB.Text.Trim());
                                cmd.ExecuteNonQuery();
                            }

                            // Εισάγουμε τις απαντήσεις της ερώτησης
                            for (int i = 1; i < _generatedControlNumber; i++)
                            {
                                cmd.Parameters.Clear();

                                // Βρίσκουμε τα Controls
                                var checkBox = (CheckBox)Controls.Find("answerCB" + i, true)[0];
                                var rtb = (RichTextBox)Controls.Find("answerBox" + i, true)[0];

                                if (string.IsNullOrEmpty(rtb.Text.Trim())) continue;

                                cmd.CommandText = "INSERT INTO answers(QuestionID, Correct, AnswerText)" +
                                                  "VALUES(@qid, @Correct, @AnswerText);";
                                cmd.Parameters.AddWithValue("qid", qid);
                                cmd.Parameters.AddWithValue("Correct", checkBox.Checked ? 1 : 0);
                                cmd.Parameters.AddWithValue("AnswerText", rtb.Text);

                                cmd.ExecuteNonQuery();
                            }

                            trans.Commit();

                            MessageBox.Show("Question added!", "", MessageBoxButtons.OK, MessageBoxIcon.Information);
                            Close();
                        }
                        catch (Exception ex)
                        {
                            trans.Rollback();
                            MessageBox.Show("An unexpected error has occurred!" + @"Pray and try again!",
                                "", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            MessageBox.Show(ex.Message);
                        }
                    }
                }
            }
            #endregion
        }

        #region Validation Methods
        /// <summary>
        /// Αυτή η μέθοδος μας δείχνει αν το input του χρήστη  
        /// είναι το σωστό 
        /// </summary>
        /// <returns></returns>
        private bool IsValid()
        {
            return _validator.ValidateRequired(levelComboBox, NewQuestionErrorProvider)
                   & _validator.ValidateRequired(QuestionRTB, NewQuestionErrorProvider)
                   & _validator.ValidateRequired(answerBox1, NewQuestionErrorProvider)
                   & _validator.ValidateRequired(answerBox2, NewQuestionErrorProvider)
                   & _validator.ValidateRequired(statusCB, NewQuestionErrorProvider)
                   & ValidateCorrectAnswer();
        }

        /// <summary>
        /// Αυτή η μέθοδος ελέγχει όλα τα Correct CheckBoxes και μας 
        /// επιστρέφει true αν είναι τουλάχιστον ένα επιλεγμένο
        /// </summary>
        /// <returns></returns>
        private bool ValidateCorrectAnswer()
        {
            if ((from Control c in Controls where c.Name.StartsWith("answerCB") select c)
                .Any(c => ((CheckBox)c).Checked))
            {
                return true;
            }
            MessageBox.Show("Please mark at least one as the correct answer.", "", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            return false;
        }

        private void ValidateReq_Valitating(object sender, CancelEventArgs e)
        {
            _validator.ValidateRequired((Control)sender, NewQuestionErrorProvider);
        }

        #endregion


    }
}
